Skip to main content

Creating Workflows

Workflows are a sequence of steps that define the logic and flow of a process. They are used to automate business processes, manage data, and coordinate tasks. The Workflow Engine provides a flexible and scalable platform for creating and executing workflows.

Workflows can be created using a code-first approach or a designer-first approach. The code-first approach involves writing workflows using a programming language, while the designer-first approach involves using a visual designer in the Workflow Studio to create workflows.

Please see the Creating Workflows Using the Workflow Studio guide for more information on the designer-first approach.

This guide details the technical, but more powerfull code-first approach to writing workflows. It covers the lifecycle methods, behind-the-scenes workings, and provides an example workflow to help you get started.

Workflow Lifecycle

A workflow in the Workflow Engine goes through several stages during its lifecycle. The main stages are:

  1. Authorization: The workflow checks if it has the necessary permissions to proceed.
  2. Initiation: The workflow starts and processes the initial payload.
  3. Hibernate: The workflow pauses and waits for a specific event or message.
  4. Resume: The workflow resumes from the hibernated state.
  5. Terminate: The workflow completes its execution and performs cleanup.
  6. Recover: The workflow recovers from a failure or restart.

Diagram of the Workflow Lifecycle

Creating a Workflow

To create a new workflow, you need to define a class that extends the Workflow class. The new class should implement the necessary lifecycle methods to handle the workflow logic.

Example Workflow Class Definition

import Workflow from '../../classes/Workflow.js';

export default class ExampleWorkflow extends Workflow {
static workflowName = "ExampleWorkflow";
static workflowVersion = "2.0";

constructor(instanceId = null, workflowDeadlineInMinutes = 1440) {
super(instanceId, workflowDeadlineInMinutes);
this.name = ExampleWorkflow.workflowName;
this.version = ExampleWorkflow.workflowVersion;
}

async OnAuthorize(payload) {
console.log(`📝 Authorization in process...`);
return true;
}

async OnInitiate(payload) {
console.log(`👤 ExampleWorkflow \${this.instanceId} initiated`);
await this.TestActivity(payload);
return { instanceId: this.instanceId, message: "Workflow initiated successfully." };
}

async TestActivity(payload) {
console.log(`👤 Running TestActivity with payload: \${JSON.stringify(payload)}`);
await this.Wait(payload.correlationId, this.ResumeAndTerminate.bind(this), 5);
}

async OnHibernate() {
console.log("👤 ******Going to Sleep*****");
}

async OnResume() {
await super.OnResume();
console.log("👤 ******Resumed...*****");
await this.ResumeAndTerminate();
}

async ResumeAndTerminate(payload) {
console.log("👤 After Resume:");
console.log(`👤 Response received for workflow \${this.instanceId}`);
await this.Terminate();
}

async OnRecover() {
await super.OnResume();
console.log("👤 ******Recovered...*****");
await this.OnInitiate(); // Start over
}

async OnTerminate() {
console.log(`👤 ExampleWorkflow \${this.instanceId} specific termination logic executed.`);
}
}

Lifecycle Methods

OnAuthorize

The OnAuthorize method is called to authorize the workflow. It should return a boolean indicating whether the authorization was successful.

async OnAuthorize(payload) {
console.log(`📝 Authorization in process...`);
return true; // or false based on the logic
}

OnInitiate

The OnInitiate method is called to initiate the workflow. It processes the initial payload and sets up the workflow state.

async OnInitiate(payload) {
console.log(`👤 ExampleWorkflow \${this.instanceId} initiated`);
await this.TestActivity(payload);
return { instanceId: this.instanceId, message: "Workflow initiated successfully." };
}

OnHibernate

The OnHibernate method is called when the workflow is hibernated.

async OnHibernate() {
console.log("👤 ******Going to Sleep*****");
}

OnResume

The OnResume method is called when the workflow is resumed.

async OnResume() {
await super.OnResume();
console.log("👤 ******Resumed...*****");
await this.ResumeAndTerminate();
}

OnTerminate

The OnTerminate method is called when the workflow is terminated.

async OnTerminate() {
console.log(`👤 ExampleWorkflow \${this.instanceId} specific termination logic executed.`);
}

OnRecover

The OnRecover method is called to recover the workflow after a failure or restart.

async OnRecover() {
await super.OnResume();
console.log("👤 ******Recovered...*****");
await this.OnInitiate(); // Start over
}

Behind the Scenes

Workflow Management

The WorkflowManagement class is responsible for managing the lifecycle of workflow instances. It provides methods to add, retrieve, remove, and persist workflow instances.

Instance Map Store

The InstanceMapStore class is a singleton that stores workflow instances in memory. It provides methods to add, retrieve, and remove instances.

Message Distribution

The MessageDistributionService class handles the distribution of messages to workflow instances. It subscribes to various events and distributes messages accordingly.

Queue Management

The QueueManager class manages a queue of messages that need to be processed. It ensures that messages are processed efficiently and handles retries.

Example Workflow

Here's an example of how to create and run the ExampleWorkflow workflow:

import ExampleWorkflow from './workflows/ExampleWorkflow.mjs';

const payload = {
alias: "agent123",
requestId: "req-456",
metadata: {
customerName: "John Doe",
customerEmail: "john.doe@example.com"
},
skipVoiceCheck: false
};

async function runWorkflow() {
const workflow = new ExampleWorkflow();
await workflow.OnAuthorize(payload);
await workflow.OnInitiate(payload);
await workflow.TestActivity(payload);
}

runWorkflow().catch(error => {
console.error("Error running ExampleWorkflow:", error);
});

Conclusion

This documentation provides a comprehensive guide on how to write a workflow using the Workflow Engine. It covers the lifecycle methods, behind-the-scenes workings, and provides an example workflow to help you get started. By following this guide, you can create robust and maintainable workflows for various use cases.

X

Graph View